﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ListAdapter.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Adapts an IList to an IList{T} where TSource inherits/implements T
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Collections
{
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
   /// Adapts an IList to an IList{T} where TSource inherits/implements T
   /// </summary>
   /// <typeparam name="T">The type of the target.</typeparam>
   /// <remarks>
   /// This class can be used to adapt any untyped IList implementation to a 
   /// typed IList&lt;T&gt; implementation. It is the consumers responsibility 
   /// to ensure the list being wrapped only contains elements of the correct type. 
   /// <example>
   /// <code>
   /// // Adapt the select items within a DataGrid
   /// IList{WorkItemViewModel} list = new ListAdapter{WorkItemViewModel}(DataGrid.SelectItems)
   /// </code> 
   /// </example>
   /// </remarks>
   public class ListAdapter<T> : IList<T> where T : class
   {
      #region Fields

      private readonly IList _adaptee;

      #endregion

      #region Constructor

      /// <summary>
      /// Initializes a new instance of the <see cref="ListAdapter&lt;T&gt;"/> class.
      /// </summary>
      /// <param name="adaptee">The source list to adapt.</param>
      public ListAdapter(IList adaptee)
      {
         _adaptee = adaptee;
      }

      #endregion

      #region IList<T> Members

      public int IndexOf(T item)
      {
         return _adaptee.IndexOf(item);
      }

      public void Insert(int index, T item)
      {
         _adaptee.Insert(index, item);
      }

      public void RemoveAt(int index)
      {
         _adaptee.RemoveAt(index);
      }

      public T this[int index]
      {
          get { return (T)_adaptee[index]; }
          set { _adaptee[index] = value; }
      }

      public void Add(T item)
      {
         _adaptee.Add(item);
      }

      public void Clear()
      {
         _adaptee.Clear();
      }

      public bool Contains(T item)
      {
         return IndexOf(item) != -1;
      }

      public void CopyTo(T[] array, int arrayIndex)
      {
         _adaptee.CopyTo(array, arrayIndex);
      }

      public int Count
      {
         get { return _adaptee.Count; }
      }

      public bool IsReadOnly
      {
         get { return _adaptee.IsReadOnly; }
      }

      public bool Remove(T item)
      {
         var index = _adaptee.IndexOf(item);
         if (index != -1)
         {
            _adaptee.RemoveAt(index);
            return true;
         }

         return false;
      }

      public IEnumerator<T> GetEnumerator()
      {
          return _adaptee.Cast<T>().GetEnumerator();
      }

      IEnumerator IEnumerable.GetEnumerator()
      {
          return GetEnumerator();
      }

        #endregion
   }
}